<template>
  <div class="designer-wrapper">
    <!-- 只显示流程图部分，隐藏左右面板 -->
    <div class="designer-canvas" tabindex="0">
      <VueFlow
        ref="vueFlowRef"
        v-model:nodes="nodes"
        v-model:edges="edges"
        :fit-view="true"
        :min-zoom="0.2"
        :max-zoom="2"
        :node-types="nodeTypes"
        :connection-mode="ConnectionMode.Loose"
        :snap-to-grid="true"
        :snap-grid="[15, 15]"
        class="vue-flow-canvas"
        :readonly="readonly"
        @node-click="onNodeClick"
        @edge-click="onEdgeClick"
      >
        <Background
          :pattern-color="'#e5e5e5'"
          :gap="20"
          :size="1"
          :offset="1"
          :pattern-id="'vue-flow-pattern'"
        />
        <MiniMap />
        <Controls />
      </VueFlow>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, computed, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { VueFlow, ConnectionMode } from '@vue-flow/core'
import { Background, MiniMap, Controls } from '@vue-flow/additional-components'
import '@vue-flow/core/dist/style.css'
import '@vue-flow/core/dist/theme-default.css'
import { GatewayNode, EventNode, TaskNode, UserTaskNode, CcNode, SubProcessNode } from './CustomNodes.js'
import html2canvas from 'html2canvas'
import { saveAs } from 'file-saver'

// 引入流程状态样式管理器
import { createProcessStatusStyleManager } from '@/components/Workflow/utils/processStatusStyleManager'

// 引入样式文件
import '../styles/process-designer.css'
import '../styles/property-panel.css'

const props = defineProps({
  processData: {
    type: Object,
    default: null
  },
  graphData: {
    type: Object,
    default: null
  },
  readonly: {
    type: Boolean,
    default: true
  },
  // 新增：流程实例数据，用于状态管理
  processInstance: {
    type: Object,
    default: null
  },
  // 新增：节点状态列表，用于状态样式管理
  nodeStatusList: {
    type: Array,
    default: () => []
  },
  // 新增：网关条件数据，用于判断网关分支激活状态
  gatewayConditions: {
    type: Array,
    default: () => []
  }
})
console.log('ProcessDesignerWrapper - props:', props)
const emit = defineEmits(['refresh', 'node-click'])

// VueFlow引用
const vueFlowRef = ref(null)

// 自定义节点类型注册
const nodeTypes = {
  gateway: GatewayNode,
  event: EventNode,
  task: TaskNode,
  userTask: UserTaskNode,
  cc: CcNode,
  subProcess: SubProcessNode
}

const nodes = ref([])
const edges = ref([])

// 解析流程图数据 - 直接使用传入的数据
const parseGraphData = (graphData) => {
  console.log('=== parseGraphData 函数开始 ===')
  console.log('传入的graphData:', graphData)
  console.log('graphData.nodes:', graphData?.nodes)
  console.log('graphData.edges:', graphData?.edges)

  try {
    // 直接使用传入的数据，不进行任何处理
    if (graphData?.nodes && Array.isArray(graphData.nodes)) {
      console.log('直接设置节点数据，节点数量:', graphData.nodes.length)
      nodes.value = graphData.nodes
    } else {
      console.log('节点数据为空或不是数组，设置为空数组')
      nodes.value = []
    }

    if (graphData?.edges && Array.isArray(graphData.edges)) {
      console.log('直接设置连线数据，连线数量:', graphData.edges.length)
      edges.value = graphData.edges
    } else {
      console.log('连线数据为空或不是数组，设置为空数组')
      edges.value = []
    }

    console.log('=== parseGraphData 函数执行完成 ===')
    console.log('最终节点数据:', nodes.value)
    console.log('最终连线数据:', edges.value)

    // 数据加载完成后，延迟触发状态样式更新
    nextTick(() => {
      setTimeout(() => {
        console.log('数据加载完成，触发状态样式更新...')
        updateProcessStatusStyles()
      }, 500)
    })
  } catch (error) {
    console.error('流程图数据设置失败:', error)
    console.error('错误堆栈:', error.stack)
    ElMessage.error('流程图数据设置失败')
  }
}

// 监听graphData变化
watch(() => props.graphData, (newGraphData) => {
  console.log('ProcessDesignerWrapper - graphData 变化:', newGraphData)
  console.log('ProcessDesignerWrapper - graphData 类型:', typeof newGraphData)
  console.log('ProcessDesignerWrapper - graphData 是否为真:', !!newGraphData)
  console.log('ProcessDesignerWrapper - graphData 是否有nodes:', newGraphData?.nodes)
  console.log('ProcessDesignerWrapper - graphData 是否有edges:', newGraphData?.edges)

  if (newGraphData) {
    console.log('ProcessDesignerWrapper - 准备调用parseGraphData')

    try {
      console.log('即将调用parseGraphData...')
      parseGraphData(newGraphData)
      console.log('ProcessDesignerWrapper - parseGraphData调用完成')
    } catch (error) {
      console.error('ProcessDesignerWrapper - parseGraphData调用失败:', error)
      console.error('错误堆栈:', error.stack)
    }
  } else {
    console.log('ProcessDesignerWrapper - graphData为空，跳过解析')
  }
}, { immediate: true })

// 监听流程实例数据变化，更新状态样式
watch(() => props.processInstance, (newProcessInstance) => {
  console.log('ProcessDesignerWrapper - processInstance 变化:', newProcessInstance)
  if (newProcessInstance && nodes.value.length > 0 && edges.value.length > 0) {
    console.log('流程实例变化，触发状态样式更新...')
    updateProcessStatusStyles()
  }
}, { deep: true })

// 流程状态样式管理器实例
const statusStyleManager = ref(createProcessStatusStyleManager(
  null,
  [],
  null,
  props.gatewayConditions
))

// 更新流程图状态样式
const updateProcessStatusStyles = () => {
  if (!nodes.value.length || !edges.value.length) {
    console.log('无法更新状态样式：图表数据为空')
    return
  }

  try {
    console.log('开始更新流程图状态样式...')
    console.log('当前节点数量:', nodes.value.length)
    console.log('当前连线数量:', edges.value.length)

    // 更新状态样式管理器的数据
    statusStyleManager.value.updateProcessInstance(props.processInstance)
    // 优先使用传入的nodeStatusList，如果没有则尝试从processInstance中获取
    const nodeStatusList = props.nodeStatusList?.length > 0
      ? props.nodeStatusList
      : (props.processInstance?.nodeStatusList || [])
    statusStyleManager.value.updateNodeStatusList(nodeStatusList)
    statusStyleManager.value.updateGraphData(props.graphData)
    // 更新网关条件数据
    statusStyleManager.value.updateGatewayConditions(props.gatewayConditions)

    console.log('状态样式管理器数据更新:', {
      processInstance: !!props.processInstance,
      nodeStatusList: nodeStatusList.length,
      graphData: !!props.graphData,
      gatewayConditions: props.gatewayConditions?.length || 0
    })

    // 使用状态样式管理器更新样式
    const { nodes: updatedNodes, edges: updatedEdges } = statusStyleManager.value.updateProcessStatusStyles(
      nodes.value,
      edges.value
    )

    // 强制更新节点和连线状态
    nodes.value = [...updatedNodes]
    edges.value = [...updatedEdges]

    console.log('流程图状态样式已更新:', {
      updatedNodes: updatedNodes.length,
      updatedEdges: updatedEdges.length
    })

    // 强制VueFlow重新渲染
    nextTick(() => {
      if (vueFlowRef.value) {
        console.log('强制VueFlow重新渲染...')
        // 触发VueFlow的更新
        const currentNodes = [...nodes.value]
        const currentEdges = [...edges.value]
        nodes.value = []
        edges.value = []
        nextTick(() => {
          nodes.value = currentNodes
          edges.value = currentEdges
        })
      }
    })
  } catch (error) {
    console.error('更新流程图状态样式失败:', error)
  }
}

// 手动刷新状态样式
const refreshStatusStyles = () => {
  console.log('手动触发状态样式刷新...')
  updateProcessStatusStyles()
}

// 节点点击事件
const onNodeClick = (event) => {
  const node = event.node
  // 发送节点点击事件
  emit('node-click', node)
}

// 连线点击事件
const onEdgeClick = (event) => {
  const edge = event.edge
  ElMessage.info(`点击了连线: ${edge.id}`)
}

// 刷新流程图
const refreshDiagram = () => {
  if (props.graphData) {
    parseGraphData(props.graphData)
  }
  emit('refresh')
}

// 放大
const zoomIn = () => {
  if (vueFlowRef.value) {
    vueFlowRef.value.zoomIn()
  }
}

// 缩小
const zoomOut = () => {
  if (vueFlowRef.value) {
    vueFlowRef.value.zoomOut()
  }
}

// 适应窗口
const fitView = () => {
  if (vueFlowRef.value) {
    vueFlowRef.value.fitView()
  }
}

// 导出图片
const exportDiagram = async (options = {}) => {
  if (vueFlowRef.value) {
    try {
      ElMessage.info('正在生成图片，请稍候...')

      // 获取VueFlow容器元素
      const vueFlowElement = vueFlowRef.value.$el
      if (!vueFlowElement) {
        throw new Error('无法获取VueFlow元素')
      }

      // 默认配置
      const defaultOptions = {
        format: 'png',
        quality: 0.95,
        scale: 2,
        backgroundColor: '#ffffff',
        filename: `流程图_${new Date().toISOString().replace(/[:.]/g, '-')}`
      }

      const exportOptions = { ...defaultOptions, ...options }

      // 配置html2canvas选项
      const html2canvasOptions = {
        useCORS: true,
        allowTaint: true,
        backgroundColor: exportOptions.backgroundColor,
        scale: exportOptions.scale,
        width: vueFlowElement.scrollWidth,
        height: vueFlowElement.scrollHeight,
        scrollX: 0,
        scrollY: 0,
        windowWidth: vueFlowElement.scrollWidth,
        windowHeight: vueFlowElement.scrollHeight
      }

      // 生成canvas
      const canvas = await html2canvas(vueFlowElement, html2canvasOptions)

      // 根据格式导出
      if (exportOptions.format === 'png') {
        // PNG格式
        canvas.toBlob((blob) => {
          if (blob) {
            const filename = `${exportOptions.filename}.png`
            saveAs(blob, filename)
            ElMessage.success('PNG图片导出成功')
          } else {
            throw new Error('生成PNG图片失败')
          }
        }, 'image/png', exportOptions.quality)
      } else if (exportOptions.format === 'jpg') {
        // JPG格式
        canvas.toBlob((blob) => {
          if (blob) {
            const filename = `${exportOptions.filename}.jpg`
            saveAs(blob, filename)
            ElMessage.success('JPG图片导出成功')
          } else {
            throw new Error('生成JPG图片失败')
          }
        }, 'image/jpeg', exportOptions.quality)
      } else if (exportOptions.format === 'svg') {
        // SVG格式（如果VueFlow支持的话）
        try {
          // 尝试使用VueFlow的内置SVG导出
          if (vueFlowRef.value.toObject) {
            const svgData = vueFlowRef.value.toObject()
            const svgBlob = new Blob([JSON.stringify(svgData)], { type: 'application/json' })
            const filename = `${exportOptions.filename}.json`
            saveAs(svgBlob, filename)
            ElMessage.success('流程图数据导出成功')
          } else {
            throw new Error('SVG导出功能不可用')
          }
        } catch (svgError) {
          // 如果SVG导出失败，回退到PNG
          console.warn('SVG导出失败，回退到PNG:', svgError)
          canvas.toBlob((blob) => {
            if (blob) {
              const filename = `${exportOptions.filename}.png`
              saveAs(blob, filename)
              ElMessage.success('PNG图片导出成功（SVG导出失败）')
            }
          }, 'image/png', exportOptions.quality)
        }
      }

    } catch (error) {
      console.error('导出图片失败:', error)
      ElMessage.error(`导出图片失败: ${error.message}`)
    }
  }
}

// 导出为PNG
const exportAsPNG = () => exportDiagram({ format: 'png' })

// 导出为JPG
const exportAsJPG = () => exportDiagram({ format: 'jpg' })

// 导出为SVG/JSON
const exportAsSVG = () => exportDiagram({ format: 'svg' })

// 暴露方法给父组件
defineExpose({
  refreshDiagram,
  zoomIn,
  zoomOut,
  fitView,
  exportDiagram,
  exportAsPNG,
  exportAsJPG,
  exportAsSVG
})
</script>

<style scoped>
.designer-wrapper {
  display: flex !important;
  flex-direction: column !important;
  height: 100% !important;
  min-height: calc(100vh - 500px) !important;
  position: relative;
}

.designer-canvas {
  flex: 1 !important;
  min-width: 0;
  height: 100% !important;
  min-height: calc(100vh - 500px) !important;
  background: #fff;
  position: relative;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
}

.vue-flow-canvas {
  width: 100% !important;
  height: 100% !important;
  min-height: calc(100vh - 500px) !important;
}

/* 确保VueFlow组件能够正确显示 */
:deep(.vue-flow) {
  width: 100% !important;
  height: 100% !important;
  min-height: calc(100vh - 500px) !important;
}

:deep(.vue-flow__viewport) {
  width: 100% !important;
  height: 100% !important;
  min-height: calc(100vh - 500px) !important;
}

:deep(.vue-flow__container) {
  width: 100% !important;
  height: 100% !important;
  min-height: calc(100vh - 500px) !important;
}

/* 确保背景网格完整覆盖 */
:deep(.vue-flow__background) {
  width: 100% !important;
  height: 100% !important;
  min-height: calc(100vh - 500px) !important;
}

:deep(.vue-flow__background-pattern) {
  width: 100% !important;
  height: 100% !important;
  min-height: calc(100vh - 500px) !important;
}

/* 夜间模式背景网格样式 */
:deep(.dark) .vue-flow__background {
  background-image:
    radial-gradient(circle, #444 1px, transparent 1px) !important;
}

:deep(.dark) .vue-flow__background circle {
  fill: #444 !important;
  r: 1px !important;
}
</style>
